package com.tom.architect02.ui10.day04;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;

import com.tom.architect02.R;

/**
 * Added by Tom on 2024/06/05.
 * 字体变色效果
 */
public class ColorTrackTextView extends androidx.appcompat.widget.AppCompatTextView {
    // 1. 实现一个文字两种颜色 - 绘制不变色字体的画笔
    private Paint mOriginPaint;
    // 1. 实现一个文字两种颜色 - 绘制变色字体的画笔
    private Paint mChangePaint;
    // 1. 实现一个文字两种颜色 - 当前的进度
    private float mCurrentProgress = 0.0f;

    // 2.实现不同朝向
    private Direction mDirection = Direction.LEFT_TO_RIGHT;
    public enum Direction {
        LEFT_TO_RIGHT, RIGHT_TO_LEFT
    }

    public ColorTrackTextView(Context context) {
        this(context, null);
    }
    public ColorTrackTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public ColorTrackTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint(context, attrs);
    }

    private void initPaint(Context context, AttributeSet attrs) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ColorTrackTextView);
        int originColor = array.getColor(R.styleable.ColorTrackTextView_originColor, getTextColors().getDefaultColor());
        int changeColor = array.getColor(R.styleable.ColorTrackTextView_changeColor, getTextColors().getDefaultColor());

        mOriginPaint = getPaintByColor(originColor);
        mChangePaint = getPaintByColor(changeColor);
        // 回收
        array.recycle();
    }

    /**
     * 1.根据颜色获取画笔
     */
    private Paint getPaintByColor(int color) {
        Paint paint = new Paint();
        paint.setColor(color); // 设置颜色
        paint.setAntiAlias(true); // 设置抗锯齿
        paint.setDither(true); // 防抖动
        // 设置字体的大小  就是TextView的字体大小
        paint.setTextSize(getTextSize());
        return paint;
    }

    // 1. 一个文字两种颜色
    // 利用clipRect的API 可以裁剪  左边用一个画笔去画  右边用另一个画笔去画  不断的改变中间值
    @Override
    protected void onDraw(Canvas canvas) {
        // super.onDraw(canvas); // 不适用系统的onDraw方法。
        // canvas.clipRect();  裁剪区域
        // 根据进度把中间值算出来，不断地计算中间值 middle
        int middle = (int) (mCurrentProgress * getWidth());
        // 从左变到右
        if (mDirection == Direction.LEFT_TO_RIGHT) {  // 左边是红色右边是黑色
            // 绘制变色. 左边用一个画笔，右边用一个画笔。
            drawText(canvas, mChangePaint, 0, middle); // 左边是红色
            drawText(canvas, mOriginPaint, middle, getWidth()); // 右边是原来的黑色
        } else {
            // 右边是红色，左边是黑色
            drawText(canvas, mChangePaint, getWidth() - middle, getWidth());
            // 左边的 绘制原始默认色
            drawText(canvas, mOriginPaint, 0, getWidth() - middle);
        }
    }

    /**
     * 绘制Text，先裁剪好画布，再绘制。或先绘制，再裁剪。
     * @param canvas 画布
     * @param paint  画笔
     * @param start  开始位置
     * @param end    结束位置
     */
    private void drawText(Canvas canvas, Paint paint, int start, int end) {
        canvas.save(); // 保存画布
        // 绘制不变色
        Rect rect = new Rect(start, 0, end, getHeight());
        canvas.clipRect(rect); // 裁剪区域
        // 我们自己来画文本
        String text = getText().toString();
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        // 获取字体的宽度
        int x = getWidth() / 2 - bounds.width() / 2;
        // 基线baseLine
        Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
        int dy = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        int baseLine = getHeight() / 2 + dy;
        canvas.drawText(text, x, baseLine, paint);// 这么画其实还是只有一种颜色
        canvas.restore(); // 释放画布，释放了才能再次裁剪。
    }
    public void setDirection(Direction direction) {
        this.mDirection = direction;
    }
    public void setCurrentProgress(float currentProgress) {
        this.mCurrentProgress = currentProgress;
        invalidate(); // 刷新UI
    }
    public void setChangeColor(int changeColor) {
        this.mChangePaint.setColor(changeColor);
    }
    public void setOriginColor(int originColor) {
        this.mOriginPaint.setColor(originColor);
    }
}
// 内涵段子 app，28节课。


